﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CustomControls.Complex;
using DBO;
using CommonLibrary;
using DBO.Economy;
using ClientBusinessManagement;
using SquadPlacer;

namespace WinFormClient
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            troopList1.onSell += new EventHandler(troopList1_onSell);
            troopList1.onBuy += new EventHandler(troopList1_onBuy);
            troopList1.onSelect += new EventHandler(troopList1_onSelect);
            menuBarControl1.onClose += new EventHandler(menuBarControl1_onClose);
            menuBarControl1.onTrash += new EventHandler(menuBarControl1_onTrash);
            menuBarControl1.onSave += new EventHandler(menuBarControl1_onSave);
            menuBarControl1.onArmyPointsSelected += new EventHandler(menuBarControl1_onArmyPointsSelected);
            pictureBox1.Hide();
        }

        void troopList1_onBuy(object sender, EventArgs e)
        {
            TroopControl ctrl = (TroopControl)sender;
            ClientDataHandler.BuySlot(ctrl.Troop);
            updatePlayerResources();
        }

        void troopList1_onSell(object sender, EventArgs e)
        {
            TroopControl ctrl = (TroopControl)sender;
            ClientDataHandler.SellSlot(ctrl.Troop);
            updatePlayerResources();
        }

        void menuBarControl1_onArmyPointsSelected(object sender, EventArgs e)
        {
            saveBefore(true);
            if (menuBarControl1.GetSelectedValue() > 0)
            {
                Game.ClearBoard();
                pictureBox1.Show();
                setGameEntities(ClientDataHandler.GetSquad(menuBarControl1.GetSelectedValue()));
            }
            else
                pictureBox1.Hide();
            recomputeUsage();
            this.updatePlayerResources();
        }
        private int prevSel_ = 0;

        public Game1 Game { get; set; }

        void menuBarControl1_onSave(object sender, EventArgs e)
        {
            if (int.Parse(costBox.Text) > menuBarControl1.GetSelectedValue())
            {
                MessageBox.Show("Point quota exceeded !");
                return;
            }
            if (troopList1.IsNegative())
            {
                MessageBox.Show("You need more troops to afford this army.");
            }
            if (menuBarControl1.GetSelectedValue() > 0 && !_saved)
            {
                _saved = true;
                ClientDataHandler.SetSquad(getGameEntities(), menuBarControl1.GetSelectedValue());
                MessageBox.Show("Squad successfuly saved.", "Saved");
            }
            else
                MessageBox.Show("Nothing to save.");
        }

        private string[] getGameEntities()
        {
            string[] res = new string[16];

            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    Entity e = Game.get(i, j);

                    if (e != null)
                        res[i * 8 + j] = e.Name;
                    else
                        res[i * 8 + j] = "";
                }
            }
            return res;
        }

        private void setGameEntities(string[] entities)
        {
            for (int i = 0; i < 16; i++)
            {
                Game.set(i / 8, i % 8, entities[i]);
            }
        }

        void menuBarControl1_onTrash(object sender, EventArgs e)
        {
            resetUsage();
            Game.ClearBoard();
            MessageBox.Show("Board cleared.");
        }

        private void resetUsage()
        {
            costBox.Text = "0";

            var okeys = _usage.Keys;
            List<string> keys = new List<string>();

            foreach (var k in okeys)
            {
                keys.Add(k);
            }

            foreach (var s in keys)
            {
                _usage[s] = 0;
            }

        }

        public event EventHandler onSelectionChanged;

        public bool ConsumeTroop(string type)
        {
            _saved = false;
            if (troopList1.ConsumeTroop(type))
            {
                selectionPortrait.Image = null;
                recomputeUsage();
                return true;
            }
            recomputeUsage();
            return false;
        }

        public void ReplenishTroop(string type)
        {
            _saved = false;
            troopList1.ReplenishTroop(type);
            recomputeUsage();
        }

        private Dictionary<string, int> _usage = new Dictionary<string, int>();

        void troopList1_onSelect(object sender, EventArgs e)
        {
            TroopControl RealSender = (TroopControl)sender;
            onSelectionChanged.Invoke(RealSender.Troop, e);
            selectionPortrait.Image = RealSender.Image;
        }

        void menuBarControl1_onClose(object sender, EventArgs e)
        {
            saveBefore(false);
            onClose.Invoke(this, null);
        }

        public event EventHandler onClose;

        public IntPtr getDrawingSurface()
        {
            return pictureBox1.Handle;
        }

        public Player Player
        {
            get { return _player; }
            set
            {
                _player = value;
                ClientDataSingleton.Instance.Player = value;
                initTroopList(value.Race);
                updatePlayerResources();
                raceLabel.Text = "(" + value.Race + ")";
                loginLabel.Text = "Welcome, " + value.Login;
            }
        }

        private void saveBefore(bool usePreviousSel)
        {
            int idx;
            if (usePreviousSel)
            {
                idx = prevSel_;
                prevSel_ = menuBarControl1.GetSelectedValue();
            }
            else
                idx = menuBarControl1.GetSelectedValue();
            if (!_saved)
            {
                var res = MessageBox.Show("There are unsaved changes. Do you want to save same before exit ?",
                    "Unsaved changes", MessageBoxButtons.YesNo);

                if (res == DialogResult.Yes)
                    ClientDataHandler.SetSquad(getGameEntities(), idx);
            }
            _saved = true;

        }

        private void updatePlayerResources()
        {
            headerResources1.Resources = ClientBusinessManagement.ClientDataHandler.GetPlayerResources();
            foreach (TroopControl ctrl in troopList1.GetTroopControls())
            {
                int u = _usage[ctrl.Troop];
                Resources Price = ClientDataSingleton.Instance.ResourceRepository.Get<Resources>(ctrl.Troop);
                if (Price.Food <= headerResources1.Resources.Food &&
                    Price.Gold <= headerResources1.Resources.Gold &&
                    Price.Stone <= headerResources1.Resources.Stone &&
                    Price.Wood <= headerResources1.Resources.Wood)
                    ctrl.ForeColor = System.Drawing.Color.Black;
                else
                    ctrl.ForeColor = System.Drawing.Color.Red;
                ctrl.TroopNumber = ClientDataHandler.CountSlots(ctrl.Troop) - u;
            }
            if (troopList1.IsNegative())
            {
                errorLabel.Text = "Current squad contains too many troops and cannot be used !";
            }
            else
            {
                errorLabel.Text = "";
            }

        }

        private void recomputeUsage()
        {
            resetUsage();
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    Entity e = Game.get(i, j);

                    if (e != null)
                    {
                        _usage[e.Name.ToLower()]++;
                        costBox.Text = (int.Parse(costBox.Text) + ArmyConstants.GetPointPrice(e.Name.ToLower())).ToString();
                    }
                }
            }
            if (int.Parse(costBox.Text) > menuBarControl1.GetSelectedValue())
                costBox.BackColor = System.Drawing.Color.Red;
            else
                costBox.BackColor = System.Drawing.Color.White;
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void initTroopList(string race)
        {
            if (race.ToLower() == "heirs")
            {
                troopList1.AddTroop("footman");
                _usage.Add("footman", 0);
                troopList1.AddTroop("archer");
                _usage.Add("archer", 0);
                troopList1.AddTroop("knight");
                _usage.Add("knight", 0);
            }
            else
            {
                troopList1.AddTroop("militian");
                _usage.Add("militian", 0);
                troopList1.AddTroop("knife_thrower");
                _usage.Add("knife_thrower", 0);
                troopList1.AddTroop("ranger");
                _usage.Add("ranger", 0);

            }
        }

        private Player _player;
        private bool _saved = true;
        private DictionnaryRepository RessourceDictionary = ClientBusinessManagement.ClientDataSingleton.Instance.ResourceRepository;

        private void MainForm_Load(object sender, EventArgs e)
        {

        }

        private void menuBarControl1_Load(object sender, EventArgs e)
        {

        }

        private void raceLabel_Click(object sender, EventArgs e)
        {

        }

    }
}
